package service

import (
	"errors"
	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
	"guns-go/global"
	"guns-go/model"
	"guns-go/model/request"
	"guns-go/model/response"
	"guns-go/utils"
)

func QuerySysConfigById(configId int) (err error, config *model.SysConfig) {
	var sysConfig *model.SysConfig
	err = global.GVA_DB.Where("id = ?", configId).Find(&sysConfig).Error
	return err, sysConfig
}

func UpdateSysConfig(config *model.SysConfig, tx *gorm.DB) error {
	return tx.Model(&config).Updates(config).Error
}

func SaveSysConfig(sysConfig *model.SysConfig, tx *gorm.DB) error {
	return tx.Create(sysConfig).Error
}

func SysConfigPage(sysConfigParam *request.SysConfigParam, c *gin.Context) (err error, result *response.PageResult) {

	var sysConfigSlice []*model.SysConfig
	db := global.GVA_DB

	if sysConfigParam != nil {

		//如果名称不为空，则带上名称搜素搜条件
		if sysConfigParam.Name != "" {
			db = db.Where("name like ?", "%"+sysConfigParam.Name+"%")
		}

		//如果常量编码不为空，则带上常量编码搜素搜条件
		if sysConfigParam.Code != "" {
			db = db.Where("code like ?", "%"+sysConfigParam.Code+"%")
		}
	}
	//查询未删除的
	db = db.Where("status <> ?", 2)
	//按类型升序排列，同类型的排在一起
	db = db.Order("group_code desc")

	var totalCount int64

	err = db.Find(&sysConfigSlice).Count(&totalCount).Error

	if err != nil {
		return err, nil
	}

	pageNo, pageSize, db := utils.DefaultPage(c, db)

	err = db.Find(&sysConfigSlice).Error

	if err != nil {
		return err, nil
	}

	return err, utils.CoverToPageResult(pageNo, pageSize, totalCount, sysConfigSlice)
}

func SysConfigAdd(sysConfigParam *request.SysConfigParam) error {

	//1.校验参数，是否有重复的名称和编码，不排除当前记录
	err := checkParamByConfig(sysConfigParam, false)

	if err != nil {
		return err
	}

	//2.构造实体
	sysConfig := new(model.SysConfig)

	err = utils.SimpleCopyProperties(sysConfig, sysConfigParam)

	if err != nil {
		return err
	}

	var zero int8
	zero = 0

	sysConfig.Status = &zero

	tx := global.GVA_DB.Begin()

	//3.保存到库中
	err = SaveSysConfig(sysConfig, tx)

	if err != nil {
		tx.Rollback()
		return err
	}
	tx.Commit()
	return nil
}

func SysConfigEdit(sysConfigParam *request.SysConfigParam) error {

	//1.根据id获取常量信息
	err, syConfig := QuerySysConfigById(sysConfigParam.Id)

	if err != nil {
		return err
	}

	if syConfig.Id == 0 {
		return errors.New("系统参数配置不存在")
	}

	//2.校验参数，是否有重复的名称和编码，排除本条记录
	err = checkParamByConfig(sysConfigParam, true)

	if err != nil {
		return err
	}

	err = utils.SimpleCopyProperties(syConfig, sysConfigParam)

	if err != nil {
		return err
	}

	//不能修改状态，用修改状态接口修改状态
	syConfig.Status = nil

	tx := global.GVA_DB.Begin()
	//3.更新记录
	err = UpdateSysConfig(syConfig, tx)

	if err != nil {
		tx.Rollback()
		return err
	}
	tx.Commit()
	//TODO 4.更新对应常量context
	return nil
}

func SysConfigDelete(sysConfigParam *request.SysConfigParam) error {

	//1.根据id获取常量信息
	err, syConfig := QuerySysConfigById(sysConfigParam.Id)

	if err != nil {
		return err
	}

	if syConfig.Id == 0 {
		return errors.New("系统参数配置不存在")
	}

	//2.不能删除系统参数
	if syConfig.SysFlag == global.Y {
		return errors.New("系统参数配置不能删除")
	}

	var two int8
	two = 2
	//3.设置状态为已删除
	syConfig.Status = &two

	tx := global.GVA_DB.Begin()
	err = UpdateSysConfig(syConfig, tx)

	if err != nil {
		tx.Rollback()
		return err
	}
	tx.Commit()
	//TODO 4.删除对应context
	return nil
}

//校验参数，是否有重复的名称和编码
func checkParamByConfig(sysConfigParam *request.SysConfigParam, isExcludeSelf bool) error {

	id := sysConfigParam.Id
	name := sysConfigParam.Name
	code := sysConfigParam.Code

	var sysConfigSlice []*model.SysConfig

	db := global.GVA_DB
	// 查询名称有无重复
	dbName := db.Where("name = ?", name)
	// 查询编码有无重复
	dbCode := db.Where("code = ?", code)

	//如果排除自己，则增加查询条件主键id不等于本条id
	if isExcludeSelf {
		dbName = dbName.Where("id <> ?", id)
		dbCode = dbCode.Where("id <> ?", id)
	}

	var countByName int64
	err := dbName.Find(&sysConfigSlice).Count(&countByName).Error

	if err != nil {
		return err
	}

	var countByCode int64
	err = dbCode.Find(&sysConfigSlice).Count(&countByCode).Error

	if err != nil {
		return err
	}

	//如果存在重复的记录，抛出异常，直接返回前端
	if countByName >= 1 {
		return errors.New("系统参数配置名称重复，请检查name参数")
	}

	if countByCode >= 1 {
		return errors.New("系统参数配置编码重复，请检查code参数")
	}

	return nil
}
